package com.ihr360.oneclick.handler;

import com.google.common.base.Throwables;
import com.ihr360.commons.vo.ErrorInfo;
import com.ihr360.oneclick.exception.OneClickException;
import com.ihr360.rest.service.MessageService;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

/**
 * 异常 handler
 *
 * @author tom
 */
@ControllerAdvice
public class OnclickExceptionHandler {

    private final static Logger logger = LoggerFactory.getLogger(OnclickExceptionHandler.class);

    @Autowired
    private MessageService messageService;

    @ResponseBody
    @ExceptionHandler(OneClickException.class)
    // 这里的httpStatus本来应该是 INTERNAL_SERVER_ERROR 但是为了兼容aggregate 中 FeignClient 对errorInfo的成功转换，所以需要改成OK
    @ResponseStatus(HttpStatus.OK)
    public ErrorInfo handleOnclickException(OneClickException e) {
        ErrorInfo errorInfo = new ErrorInfo();
        try {
            String message = getMessage(e);
            errorInfo.setMessage(message);
            errorInfo.setCode("-1");
        } catch (Throwable throwable) {
            logger.error(e.getMessage() + Throwables.getStackTraceAsString(throwable));
        }
        return errorInfo;
    }

    private String getMessage(OneClickException e) {
        String key = e.getMessageKey();
        String message = e.getMessage();
        if (!StringUtils.isEmpty(key)){
            Locale locale = LocaleContextHolder.getLocale();
            if(e.getArgs() != null && e.getArgs().length >0) {
                Map<String, Object[]> messageParamMap = new HashMap<>();
                messageParamMap.put(key, e.getArgs());
                Map<String, String> messageMap = messageService.messagesMap(locale.getLanguage(), messageParamMap);
                String i18nMessage = messageMap.get(key);
                return key.equals(i18nMessage) ? message : i18nMessage;
            } else{
                String i18nMessage = messageService.message(locale.getLanguage(), key);
                return key.equals(i18nMessage) ? message : i18nMessage;
            }
        }
        return message;
    }
}
